﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using Kailua.WSSLists;
using System.Net;
using System.Xml;
using net.windward.utils.ado;
using System.Web.Services.Protocols;
using log4net;

namespace Kailua.net.windward.utils.ado.SPList.custom
{
    /// <summary>
    /// WrSPListServer creates IWrDatabase objects which can be queried for SharePoint list data.
    /// Databases in this case are SharePoint websites (SPWeb).
    /// </summary>
    public class WrSPListServer2 : IWrServer
    {
        /// <summary>
        /// The URL of the SPWeb to retrieve list data from.
        /// </summary>
        private string spWebUrl;

        /// <summary>
        /// Creates a new WrSPListServer from the specified URL.
        /// </summary>
        /// <param name="url"></param>
        public WrSPListServer2(string url)
        {
            spWebUrl = url;
        }

        private static ILog log = LogManager.GetLogger(typeof(WrSPListServer2));

        #region IWrServer Members

        /// <summary>
        /// The URL of the SPWeb to retrieve list data from.
        /// </summary>
        public string Name
        {
            get { return spWebUrl; }
        }

        /// <summary>
        /// Creates a WrSPListDatabase object.
        /// </summary>
        /// <param name="database">The name of the database.</param>
        public IWrDatabase CreateDatabase(string database)
        {
            return new WrSPListDatabase2(spWebUrl, database);
        }
        /// <summary>
        /// Gets the list of databases for this server.  In this case, only a single WrSPListDatabase object is returned
        /// for the specified SPWeb.
        /// </summary>
        /// <param name="credentials"></param>
        /// <returns></returns>
        public IWrDatabase[] GetDatabases(WrCredentials credentials)
        {
            try
            {
                // Use arrayList and add all the databases, return them.
                ArrayList rtn = new ArrayList();

                Lists ls = new Lists();
                ls.PreAuthenticate = true;
                ls.Credentials = new NetworkCredential(credentials.Username, credentials.Password);
                ls.Url = spWebUrl + @"/_vti_bin/lists.asmx";

                foreach (XmlNode list in ls.GetListCollection().ChildNodes)
                {
                    //(provider, "", Name, list.Attributes["Title"].Value + "    ," + list.Attributes["ID"].Value)
                    string listTitle = list.Attributes["Title"].Value;
                    string listId = list.Attributes["ID"].Value;
                    rtn.Add(new WrSPListDatabase2(spWebUrl, listTitle, listId));
                }
                return (WrSPListDatabase2[])rtn.ToArray(typeof(WrSPListDatabase2));
            }
            catch (SoapException ex)
            {
                string detail = ex.Detail.OuterXml;
                throw new Exception(detail, ex);
            }
            catch (Exception ex)
            {
                if (log.IsWarnEnabled)
                    log.Warn("Error occured getting databases from SharePoint list data.", ex);
                throw;
            }
        }
        /// <summary>
        /// Gets the list of databases for this server.  In this case, only a single WrSPListDatabase object is returned
        /// for the specified SPWeb.
        /// </summary>
        /// <param name="connStr"></param>
        /// <returns></returns>
        public IWrDatabase[] GetDatabases(string connStr)
        {
            // parse the connection string
            Hashtable keyPairs = SPListConnection.ParseConnectionString(connStr);
            this.spWebUrl = (string)keyPairs["URL"];
            WrCredentials credentials = CreateWrCredentials(keyPairs);

            // run GetDatabases(WrCredentials)
            return GetDatabases(credentials);
        }
        /// <summary>
        /// Creates WrCredentials from the specified Hashtable of connection string key-pairs.
        /// </summary>
        /// <param name="keyPairs"></param>
        /// <returns></returns>
        internal static WrCredentials CreateWrCredentials(Hashtable keyPairs)
        {
            WrCredentials credentials = null;
            string user = null;
            string password = null;
            string domain = null;
            if (keyPairs.ContainsKey("USER"))
            {
                user = (string)keyPairs["USER"];
                password = (string)keyPairs["PASSWORD"];
                if (keyPairs.ContainsKey("DOMAIN"))
                    domain = (string)keyPairs["DOMAIN"];
            }
            if (user != null)
            {
                if (domain != null)
                    credentials = new WrCredentials(domain, user, password);
                else
                    credentials = new WrCredentials(user, password);
            }
            else
                credentials = new WrCredentials();
            return credentials;
        }

        #endregion

        #region IComparable Members

        /// <summary>
        /// Not implemented.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int CompareTo(object obj)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
